home *** CD-ROM | disk | FTP | other *** search
- /*
- * WWShinyRustyMetal.sl -- faked environment shiny metal with specks of rust
- *
- * hacked from Pixar's rsmetal and Larry Gritz's rustymetal shaders
- *
- * DESCRIPTION:
- * A rough metal surface with controllable rust spots. The rust pattern
- * is basically thresholded turbulence (summed abs(snoise)). Where it's
- * rusty, shade like rust colored matte, and also make it bumpy (like
- * the corrosion is kind of grainy). Where there is no rust, shade like
- * regular metal. All computations are done in shader space.
- *
- * PARAMETERS
- * metalKa, metalKs, metalroughness - control the appearance of the metal.
- * rustKa, rustKd, rustcolor - control the appearance of the rust.
- * txtscale - overall scaling factor of the rust pattern.
- * rusty - 0=no rust, larger for more rust, 1=completely rusty
- * rustbump - controls the "bumpiness" of the rusty areas.
- *
- * ANTIALIASING:
- * The fractal sum used to determine the rust pattern chooses a number of
- * octaves to sum based on the shader sampling rate. This helps to keep
- * aliasing under control.
- *
- * AUTHOR: Larry Gritz + Pixar, with minor surgery by wave
- *
- * HISTORY:
- * 27 Feb 59 - wave
- *
- */
-
-
-
- /* Signed noise varies from -1 to 1 (like Perlin uses) */
- #define snoise(x) (2*noise(x)-1)
-
- /* Maximum number of octaves */
- #define MAXOCTAVES 8
-
-
- surface
- WWRustyShinyMetal (float metalKa = 1, metalKs = 1, metalroughness = .1;
- float rustKa = 1, rustKd = 1;
- color rustcolor = color (.437, .084, 0);
- float txtscale = 1;
- float rusty = 0.2;
- float rustbump = 0.035;
- float Kr = 0.6;
- )
- {
- point Nf, V; /* normal and view vector used for shading */
- point Nrust; /* perturbed normal for the rusty areas */
- point PP; /* shade space point */
- float i, sum = 0, a = 1; /* Loop control for fractal sum */
- float alimit; /* Limit sum to do simple antialiasing */
- float rustiness; /* Result: how rusty is this point? */
- color Cmetal = 0, Crust = 0; /* Computed colors of metal & rust */
- float w;
- point D;
- color Cr;
-
-
- /* Sum several octaves of abs(snoise), i.e. turbulence. Limit the
- * number of octaves by the estimated change in PP between adjacent
- * shading samples.
- */
- /* change from "shader" to "object" so that we can use for animation */
- PP = txtscale * transform ("object", P);
- alimit = sqrt (area(PP));
- for (i = 0; i < MAXOCTAVES && a > alimit; i += 1) {
- sum += a * abs(snoise(PP));
- PP *= 2;
- a /= 2;
- }
- /* If it's rusty, also add a high frequency bumpiness to the normal */
- Nrust = calculatenormal (P + rustbump * snoise(PP) * normalize(N));
-
- /* Scale the rust appropriately, modulate it by another noise
- * computation, then sharpen it by squaring its value.
- */
- rustiness = step (1-rusty, clamp (sum,0,1));
- rustiness *= clamp (abs(snoise(PP)), 0, .08) / 0.08;
- rustiness *= rustiness;
-
- /* If we have any rust, calculate the color of the rust, taking into
- * account the perturbed normal and shading like matte.
- */
- if (rustiness > 0) {
- Nf = faceforward (normalize(Nrust),I);
- Crust = rustcolor * (rustKa*ambient() + rustKd*diffuse(Nf));
- }
- /* If we have any metal, calculate the color of the metal, using the
- * original (smooth) normal and the usual metal illumination model.
- */
- /* also add in the fake environment stuff, but only for the shiny part */
- if (rustiness < 1) {
- Nf = faceforward (normalize(N),I);
-
- /* do the fake environment stuff here */
- V = normalize(-I);
- D = reflect(V, Nf) ;
- D = transform("world", D) - transform("world", (0.,0.,0.)) ;
- w = 0.6 * noise(D * 2.5) + 0.2 * noise(D * 5) + 0.1 * noise(D * 10) + 0.05 * noise(D * 20);
- w = w * w * w;
- Cr = Kr * mix(color(0,0,0), color(1,1,1), w );
-
- Cmetal = Cs * (metalKa*ambient() + metalKs*specular(Nf,V,metalroughness) + Cr);
- }
-
- /* Now blend the metal and rust colors depending on the computed value
- * of the rustiness.
- */
- Oi = Os;
- Ci = Oi * mix (Cmetal, Crust, rustiness);
- }
-